// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Permissive License.
// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
// All other rights reserved.

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Collections;

namespace RealWorld.Grids
{
    public class DropDownField : BoundField
    {
        //DataSourceView dataView;

        #region Properties

        public string ListDataTextField
        {
            get
            {
                object val = this.ViewState["ListDataTextField"];
                if (null == val)
                {
                    return String.Empty;
                }

                return (string)val;
            }
            set
            {
                if (0 != String.CompareOrdinal(value, this.ListDataTextField))
                {
                    this.ViewState["ListDataTextField"] = value;
                    base.OnFieldChanged();
                }
            }
        }

        public string ListDataValueField
        {
            get
            {
                object val = this.ViewState["ListDataValueField"];
                if (null == val)
                {
                    return String.Empty;
                }

                return (string)val;
            }
            set
            {
                if (0 != String.CompareOrdinal(value, this.ListDataValueField))
                {
                    this.ViewState["ListDataValueField"] = value;
                    base.OnFieldChanged();
                }
            }
        }

        [IDReferenceProperty(typeof(DataSourceControl)), Themeable(false)]
        public string ListDataSourceID
        {
            get
            {
                object val = this.ViewState["ListDataSourceID"];
                if (null == val)
                {
                    return String.Empty;
                }

                return (string)val;
            }
            set
            {
                if (0 != String.CompareOrdinal(value, this.ListDataSourceID))
                {
                    this.ViewState["ListDataSourceID"] = value;
                    base.OnFieldChanged();
                }
            }
        }

        #endregion

        protected override object GetDesignTimeValue()
        {
            return 0;
        }

        protected override void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState)
        {
            if((!this.ReadOnly && (0!= (rowState & DataControlRowState.Edit)))
                || 0 != (rowState & DataControlRowState.Insert))
            {
                DropDownList ddl = new DropDownList();
                ddl.ToolTip = this.HeaderText;

                if (!String.IsNullOrEmpty(this.DataField) && 0 != (rowState & DataControlRowState.Edit))
                {
                    ddl.DataBinding += new EventHandler(HandleDataBinding);
                    ddl.DataBound += new EventHandler(HandleDataBound);
                }

                cell.Controls.Add(ddl);
            }
            else if (!String.IsNullOrEmpty(this.DataField))
            {
                Label lbl = new Label();
                lbl.DataBinding += new EventHandler(HandleDataBinding);
                cell.Controls.Add(lbl);
            }
        }

        public override void ExtractValuesFromCell(System.Collections.Specialized.IOrderedDictionary dictionary, DataControlFieldCell cell, DataControlRowState rowState, bool includeReadOnly)
        {
            if (cell.HasControls() && cell.Controls[0] is DropDownList)
            {
                DropDownList ddl = (DropDownList)cell.Controls[0];
                dictionary[this.DataField] = String.IsNullOrEmpty(ddl.SelectedValue) ? null : ddl.SelectedValue;               
            }
        }

        /// <summary>
        /// Callback from the datasourceview.
        /// </summary>
        /// <param name="data"></param>
        void DataSourceCallback(IEnumerable data)
        {
            this.data = data;
        }

        IEnumerable data = null;

        void HandleDataBinding(object sender, EventArgs e)
        {
            Control ctrl = (Control)sender;

            object rawVal = GetValue(ctrl.NamingContainer);
            string val = (null == rawVal ? null : rawVal.ToString());

            if (null == data)
            {
                //Cache the data from the DataSourceControl, so that we only get the data once.  If 
                //we just set the DataSourceID on the dropdown, the select command would get called 
                //once for each row.
                DataSourceControl dsc = WebControlHelper.RecursiveFindControl(this.Control.NamingContainer, this.ListDataSourceID) as DataSourceControl;
                if (null != dsc)
                {
                    DataSourceView dsv = ((IDataSource)dsc).GetView("DefaultView");
                    dsv.Select(DataSourceSelectArguments.Empty, new DataSourceViewSelectCallback(this.DataSourceCallback));
                }
            }

            if (ctrl is DropDownList)
            {
                DropDownList ddl = (DropDownList)ctrl;
                ddl.DataTextField = this.ListDataTextField;
                ddl.DataValueField = this.ListDataValueField;
                ddl.DataSource = this.data;
            }
            else if (ctrl is Label)
            {
                Label lbl = (Label)ctrl;

                DropDownList temp = new DropDownList();
                temp.DataTextField = this.ListDataTextField;
                temp.DataValueField = this.ListDataValueField;
                temp.DataSource = this.data;
                temp.Visible = false;

                lbl.Controls.Add(temp);
                temp.DataBind();

                lbl.Text = String.Empty;
                foreach (ListItem li in temp.Items)
                {
                    if (0 == String.Compare(li.Value, val))
                        lbl.Text = li.Text;
                }
            }
        }

        void HandleDataBound(object sender, EventArgs e)
        {
            Control ctrl = (Control)sender;
            string val = GetValue(ctrl.NamingContainer) as string;

            DropDownList ddl = ctrl as DropDownList;
            if (null != ddl)
            {
                //make sure the appropriate value is selected
                ListItem li = ddl.Items.FindByValue(val);
                if (null != li)
                {
                    li.Selected = true;
                }
            }
        }


    }
}
